package com.ygqh.baby.controller.admin;

import com.ygqh.baby.ao.Message;
import com.ygqh.baby.ao.UserType;
import com.ygqh.baby.ao.ValidateCode;
import com.ygqh.baby.model.YgLoginModel;
import com.ygqh.baby.po.YgUser;
import com.ygqh.baby.service.AdminUserService;
import com.ygqh.baby.service.SmsService;
import com.ygqh.baby.service.YgUserService;
import com.ygqh.baby.service.impl.DocumentConstant;
import com.ygqh.baby.utils.CommonUtil;
import com.ygqh.baby.utils.PropertiesUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
@RequestMapping("/admin")
public class AdminController extends BaseController<Object, java.lang.Long> {

    @Autowired
    private AdminUserService adminUserService;
    @Autowired
    private DocumentConstant documentConstant;
    @Autowired
    private YgUserService ygUserService;
    @Autowired
    private SmsService smsService;

    @Value("${validate.send.count}")
    private Long validateSendCount;

    @Value("${validate.send.interval}")
    private Long validateSendInterval;

    @Value("${validate.valid.time}")
    private Long validateValidTime;
    @Value("${sms.isSend}")
    private Boolean isSend;


    @RequestMapping(value = "login", method = RequestMethod.GET)
    public String login(HttpServletRequest request) throws Exception {

        return "redirect:/pages/login.html";
    }

    @RequestMapping(value = "login", method = RequestMethod.POST)
    @ResponseBody
    public Message loginPost(HttpServletRequest request, String username, String callback, String password, HttpServletResponse response) throws Exception {

        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        YgLoginModel model = new YgLoginModel("LOGIN_SUCCESS", documentConstant.LOGIN_SUCCESS);
        try {
            subject.login(token);
        } catch (UnknownAccountException e) {
            model = new YgLoginModel("UNKNOWN_ACCOUNT", documentConstant.UNKNOWN_ACCOUNT);
        } catch (IncorrectCredentialsException e) {
            e.printStackTrace();
            model = new YgLoginModel("INCORRECTCREDENTIALS", documentConstant.INCORRECTCREDENTIALS);
        } catch (Exception e) {
            e.printStackTrace();
            model = new YgLoginModel("UNKNOWN_ERROR", documentConstant.UNKNOWN_ERROR);
        }
        model.setUser((YgUser) subject.getPrincipal());
        return Message.success(model);


    }

    @RequestMapping(value = "logout")
    @ResponseBody
    public Message logout(HttpServletRequest request, String username, String password) throws Exception {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return SUCCESS_MESSAGE;
    }

    @RequestMapping("create")
    @ResponseBody
    @RequiresPermissions("product:create")//执行queryItems需要"item:query"权限
    public String create() {

        return "ok";
    }

    /**
     * 发送验证码-----------------------正常
     *
     * @param username
     * @param callback
     * @return
     * @throws Exception
     */
    @RequestMapping("/sendValidateCode")
    @ResponseBody
    public Message sendValidateCode(@RequestParam(required = true) String username) throws Exception {
        String validateCodeString;
        if (isSend) {
            validateCodeString = CommonUtil.generatorSmsValidateCode() + "";
        } else {
            validateCodeString = "123456";
        }
        ValidateCode originalValidateCode = ygUserService.selectValidateCodeToRedis(username);
        ValidateCode validateCode = new ValidateCode(validateCodeString, 0L);

        if (originalValidateCode != null) {
            // 判断发送信息次数是否超过限定值
            if (originalValidateCode.getSendCount() > validateSendCount) {
                return Message.error(documentConstant.SEND_COUNT_OVER, "SEND_COUNT_OVER");
            }

            if (originalValidateCode.getSendCount() > 1) {
                // 判断是否发送过于频繁
                Long currentTime = System.currentTimeMillis();
                if ((currentTime - originalValidateCode.getSendTime()) / 1000 < validateSendInterval) {
                    return Message.error(documentConstant.SEND_HIGH_FREQUENCY, "SEND_HIGH_FREQUENCY");
                }
            }

            Long count = originalValidateCode.getSendCount() + 1L;
            validateCode.setSendCount(count);
            validateCode.setSendTime(System.currentTimeMillis());
        } else {
            validateCode.setSendTime(System.currentTimeMillis());
        }
        String smsContent = PropertiesUtil.get("/prop/sms.properties", "sms.content", new String[]{validateCodeString});
        smsService.sendSms(username, smsContent, true);
        int expire = (validateValidTime.intValue() * 60 * 1000);
        ygUserService.saveValidateCodeToRedis(username, validateCode, expire);
        return Message.success(documentConstant.VALIDATE_CODE_SEND_SUCCESS, documentConstant.VALIDATE_CODE_SEND_SUCCESS);
    }

    @RequestMapping(value = "/validateCodeLogin")
    @ResponseBody
    public Message validateCodeLogin(@RequestParam() String username, @RequestParam() String validateCode,
                                     HttpServletRequest request, HttpServletResponse response) throws Exception {

        YgUser user = ygUserService.findByUserName(username);
        YgLoginModel model = new YgLoginModel("LOGIN_SUCCESS", documentConstant.LOGIN_SUCCESS);

        if (user == null) {
            model = new YgLoginModel("UNKNOWN_ACCOUNT", documentConstant.UNKNOWN_ACCOUNT);
            return Message.error(model);
        }

        ValidateCode rightValidateCode = ygUserService.selectValidateCodeToRedis(username);

        // 判断是否匹配
        if (rightValidateCode == null || !rightValidateCode.getCode().equals(validateCode)) {
            return Message.error(documentConstant.VALIDATE_CODE_NO_MATCHING, "VALIDATE_CODE_NO_MATCHING");
        }

        Long currentTime = System.currentTimeMillis();
        Long minute = (currentTime - rightValidateCode.getSendTime()) / 1000 / 60;

        // 判断是否失效
        if (minute > validateValidTime) {
            return Message.error(documentConstant.VALIDATE_INVALID, "VALIDATE_INVALID");
        }

        this.loginSilent(username, user.getPassword());
        model.setUser(user);
        return Message.success(model);

    }

    private YgLoginModel loginSilent(String username, String pwd) {
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, pwd);
        YgLoginModel model = new YgLoginModel("LOGIN_SUCCESS", documentConstant.LOGIN_SUCCESS);
        try {
            subject.login(token);
        } catch (UnknownAccountException e) {
            model = new YgLoginModel("UNKNOWN_ACCOUNT", documentConstant.UNKNOWN_ACCOUNT);
        } catch (IncorrectCredentialsException e) {
            model = new YgLoginModel("INCORRECTCREDENTIALS", documentConstant.INCORRECTCREDENTIALS);
        } catch (Exception e) {
            e.printStackTrace();
            model = new YgLoginModel("UNKNOWN_ERROR", documentConstant.UNKNOWN_ERROR);
        }
        subject.isPermitted("create");
        return model;

    }

    /**
     * 用户是否存在
     *
     * @param username
     * @return
     */
    @RequestMapping("/userIsExist")
    @ResponseBody
    public Message userIsExist(@RequestParam(required = true) String username) {
        YgUser user = ygUserService.findByUserName(username, UserType.Agent);
        if (user == null) {
            return Message.success(false);
        } else {
            return Message.success(true);
        }
    }
}
